package com.wjc.myktapplication.page.project.ImageDemo

import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.util.AttributeSet
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.widget.OverScroller
import androidx.core.view.GestureDetectorCompat
import com.wjc.basemodule.utils.LogTools
import com.wjc.common.dp
import com.wjc.common.getBitmapWithRes
import com.wjc.myktapplication.R

/**
 * ClassName: com.wjc.myktapplication.page.project.ImageDemo
 * Description:
 * JcChen on 2021.09.26.07:52
 */

private const val EXTRA_SCALE_FRACTION = 1.5f
private val IMAGE_SIZE = 300f.dp.toInt()

class ScalableImageView(context: Context, attributeSet: AttributeSet) :
    View(context, attributeSet), GestureDetector.OnGestureListener,
    GestureDetector.OnDoubleTapListener, Runnable {
    val TAG = "ScalableImageView"

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)

    private var originalOffsetX = 0f
    private var originalOffsetY = 0f
    private var offsetX = 0f
    private var offsetY = 0f

    private var smallScale = 0f
    private var bigScale = 0f

    private var big = false

    val bitmap = getBitmapWithRes(resources, R.mipmap.ic_c_001, IMAGE_SIZE)

    // 手势
    private val gestureDetector = GestureDetectorCompat(context, this)

    private val scroller = OverScroller(context)


    private var scaleParam = 0f
        set(value) {
            field = value
            invalidate()
        }

    private val scaleAnimator: ObjectAnimator by lazy {
        ObjectAnimator.ofFloat(this, "scaleParam", 0f, 1f)
    }


    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        originalOffsetX = (width - IMAGE_SIZE) / 2f
        originalOffsetY = (height - IMAGE_SIZE) / 2f
        LogTools.d(TAG, ": originalOffsetX=$originalOffsetX,width = $width")

        if (bitmap.width / bitmap.height.toFloat() > width / height.toFloat()) {
            smallScale = width / bitmap.width.toFloat()
            bigScale = height / bitmap.height.toFloat() * EXTRA_SCALE_FRACTION
        } else {
            smallScale = height / bitmap.height.toFloat()
            bigScale = width / bitmap.width.toFloat() * EXTRA_SCALE_FRACTION
        }
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.translate(offsetX, offsetY)
        val scale = if (big) bigScale else smallScale
        canvas.scale(scale, scale, width / 2f, height / 2f)
        canvas.drawBitmap(bitmap, originalOffsetX, originalOffsetY, paint)
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        return gestureDetector.onTouchEvent(event)
    }

    override fun onDown(e: MotionEvent?): Boolean {
        return true;// 控制整个流的入口
    }

    override fun onShowPress(e: MotionEvent?) {

    }

    // 类似单击
    override fun onSingleTapUp(e: MotionEvent?): Boolean {
        return true // true/false 都不影响，仅仅记录
    }

    override fun onScroll(
        downEvent: MotionEvent?,
        currentEvent: MotionEvent?,
        distanceX: Float,
        distanceY: Float
    ): Boolean {
        if (big) {
            offsetX -= distanceX
            offsetX = minOf(offsetX, (bitmap.width * bigScale - width) / 2)
            offsetX = maxOf(offsetX, -(bitmap.width * bigScale - width) / 2)

            offsetY -= distanceY
            offsetY = minOf(offsetY, (bitmap.height * bigScale - height) / 2)
            offsetY = maxOf(offsetY, -(bitmap.height * bigScale - height) / 2)

            invalidate()
        }
        return false
    }

    override fun onLongPress(e: MotionEvent?) {
    }

    // 惯性滑动
    override fun onFling(
        downEvent: MotionEvent?,
        currentEvent: MotionEvent?,
        velocityX: Float,
        velocityY: Float
    ): Boolean {
        if (big) {
            scroller.fling(
                offsetX.toInt(),
                offsetY.toInt(),
                velocityX.toInt(),
                velocityY.toInt(),
                (-(bitmap.width * bigScale - width) / 2).toInt(),
                ((bitmap.width * bigScale - width) / 2).toInt(),
                (-(bitmap.height * bigScale - height) / 2).toInt(),
                ((bitmap.height * bigScale - height) / 2).toInt(), 40f.dp.toInt(), 40f.dp.toInt()
            )
            postOnAnimation(this)
        }
        return false
    }

    override fun run() {
        if (scroller.computeScrollOffset()) {
            offsetX = scroller.currX.toFloat()
            offsetY = scroller.currY.toFloat()
            invalidate()
            postOnAnimation { this }
        }
    }

    override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
        return false
    }

    // 双击、防手抖
    override fun onDoubleTap(e: MotionEvent?): Boolean {
        big = !big
        if (big) scaleAnimator.start()
        else scaleAnimator.reverse()
        return false
    }

    override fun onDoubleTapEvent(e: MotionEvent?): Boolean {
        return false
    }

}